// 2014-02-01 Tyrghen
//---------------------------------------------
// Usage:
//  [["B_Soldier_F","B_Soldier_02_f","B_Soldier_03_f"], "marker_spawn", west,"patrol"] call edt_fnc_spawn;
//  ["B_Heli_Attack_01_F", [12012,4563,300], west,"patrol"] call edt_fnc_spawn;
//  ["Land_PowLines_Transformer_F", "marker_transfo"] call edt_fnc_spawn;
//  [(getArray(configFile/"CfgGroups"/"East"/"OPF_F"/"Infantry"/"OIA_Squad")), "marker_spawn", east,"defend"] call edt_fnc_spawn;
//  [["B_Heli_Attack_01_F","B_Heli_Attack_01_F"], [12012,4563,300], west,"attack",["marker_target",300]] call edt_fnc_spawn;
//  [["O_MRAP_02_hmg_F","O_MRAP_02_hmg_F"], "marker_reinforcement", east,"guard"] call edt_fnc_spawn;
//  [["O_Soldier_TL_F","O_Soldier_GL_F","O_Soldier_F"], "marker_town", east,"homed"] call edt_fnc_spawn;
//  [["O_soldier_M_F","O_soldier_M_F"], "marker_town", east,"sniper"] call edt_fnc_spawn;
//---------------------------------------------
// Purpose:
// Creates a group of units and assign them a task to perform (attack, defend, patrol, guard, sniper, homed).
// Or creates an object at a given location.
// 
// Parameters:
// Optional Parameters:
//
// Returns:
// The group of the units (units might be created on the headless if any, so there could be a delay) or an array of static objects if it wasn't units
//---------------------------------------------
// Objectif:
// Crée un groupe d'unités et leur assigne une tâche à effectuer (attaquer, défendre, patrouille, garder, sniper ou homé)
//
// Paramètres:
// Paramètres Optionnels:
//
// Renvoie:
// Le groupe des unités (les unités pourraient être créées sur le headless s'il y en a un, donc il peut y avoir un délai) ou un tableau d'objets statiques s'il ne s'agissait pas d'unités
//---------------------------------------------

//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "editor\fn_spawn.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

if (!isServer && !(call MCFUNC(isHC))) exitWith { TRACE("Not Server or HC") };

TRACE_1("Start",_this);
TMFPROFILERSTART;

private ["_types","_marker","_error","_special","_shape","_objs","_obj","_obj_type","_obj_group","_activity","_activity_params","_special_param","_is_units","_hc_id"];
DEFAULT_PARAM(_types,0,"");
DEFAULT_PARAM(_marker,1,"");
DEFAULT_PARAM(_obj_group,2,GVAR(side_enemy));
DEFAULT_PARAM(_activity,3,""); // Activity or 'Special' parameter when creating a static object
DEFAULT_PARAM(_activity_params,4,[]);

_error = false;
_objs = [];
if (IS_STRING(_types)) then {
	_error = (_types == "");
	_types = [_types];
};
_shape = [_marker] call FFUNC(toShape);
if (count (_shape select TMF_SHAPE_CENTER) <= 0) then { _error = true };
if (_error) exitWith { ERROR_1("Invalid shape",_this); _objs};

TRACE_1("Params",ARR_5(_types,_shape,_obj_group,_activity,_activity_params));
_is_units = false;
{ if (_x isKindOf "AllVehicles" || _x isKindOf "Man") exitWith { _is_units = true };
} foreach _types;

if (_is_units) then {
	_obj_group = [_obj_group] call FFUNC(createGroup);
	if (isnull _obj_group) exitWith { ERROR_1("Invalid Group",_this); _objs};
	_objs set [count _objs, _obj_group];
	
	_hc_id = -1;
	if (0 call MCFUNC(hasHC) && {!(0 call MCFUNC(isHC))}) then {
		_hc_id = 0 call MCFUNC(getHC);
	};
	if (_hc_id >= 0) then {
		DEBUG_1("Calling HC Spawn",_hc_id);
		[QGVAR(hc_spawn), [[_types,_marker,_obj_group,_activity,_activity_params],_hc_id]] call FFUNC(callevent);
	} else {
		DEBUG_1("Already on HC or no HC");
		
		if (!IS_STRING(_activity)) then { _activity = ""; };
		_activity = switch (tolower(_activity)) do {
			case "defend": { "defend" };
			case "patrol": { "patrol" };
			case "defendre": { "defend" };
			case "défendre": { "defend" };
			case "patrouille": { "patrol" };
			case "patrouiller": { "patrol" };
			case "attack": { "attack" };
			case "attaque": { "attack" };
			case "attaquer": { "attack" };
			case "ambush": { "ambush" };
			case "embuscade": { "ambush" };
			case "guard": { "guard" };
			case "garde": { "guard" };
			case "garder": { "guard" };
			case "sniper": { "sniper" };
			case "snipers": { "sniper" };
			case "homed": { "homed" };
			case "home": { "homed" };
			case "homé": { "homed" };
			case "civ": { "civ" };
			case "civilian": { "civ" };
			case "civil": { "civ" };
			case "civils": { "civ" };
			default { _activity };
		};

		{
			_obj_type = _x;
			switch (true) do {
				case (_obj_type isKindOf "Man"): {
					TRACE_1("Creating Unit",_obj_group);
					_obj = [TMF_SERVER_INSTANCE_ID,_obj_type, _obj_group, (_shape select TMF_SHAPE_CENTER), ((_shape select TMF_SHAPE_WIDTH) max (_shape select TMF_SHAPE_HEIGHT)), "", "corporal",([TMF_SERVER_INSTANCE_ID] call FFUNC(getUnitSkill))] call FFUNC(createUnit);
					_obj setDir (_shape select 2);
					//_objs set [count _objs, _obj];
				};
				case (_obj_type isKindOf "AllVehicles"): {
					TRACE_1("Creating Vehicle",_obj_group);
					_obj = [TMF_SERVER_INSTANCE_ID, _obj_type, _obj_group, (_shape select TMF_SHAPE_CENTER), ((_shape select TMF_SHAPE_WIDTH) max (_shape select TMF_SHAPE_HEIGHT)), [], (_shape select TMF_SHAPE_ANGLE),([TMF_SERVER_INSTANCE_ID] call FFUNC(getUnitSkill))] call FFUNC(spawnVehicle);
					(_obj select 0) setDir (_shape select 2);
					//_objs set [count _objs, _obj];
				};
				default {
					TRACE_1("Creating Object",_obj_group);
					_obj = [TMF_SERVER_INSTANCE_ID, _obj_type,(_shape select TMF_SHAPE_CENTER),[],((_shape select TMF_SHAPE_WIDTH) max (_shape select TMF_SHAPE_HEIGHT)),_activity] call FFUNC(createVehicle);
					_objs set [count _objs, _obj];
					_obj setPos (_shape select TMF_SHAPE_CENTER);
					_obj setDir (_shape select TMF_SHAPE_ANGLE);
					_obj setVectorUp [0,0,1];
				};
			};
		} foreach _types;
		if (_activity != "") then {
			_activity_params = [[_obj_group],_activity_params] call FFUNC(arrayPushStack);
			TRACE_1("Activity",ARR_3(_activity,_activity_params,_objs));
			switch (_activity) do {
				case "defend":{
					_activity_params spawn FFUNC(defend);
				};
				case "patrol":{
					_activity_params spawn FFUNC(patrol);
				};
				case "attack":{
					_activity_params spawn FFUNC(attack);
				};
				case "ambush":{
					_activity_params spawn FFUNC(ambush);
				};
				case "guard":{
					private ["_wp"];
					_obj_group call FFUNC(deleteWaypoints);
					_wp = _obj_group addWaypoint [position (leader _obj_group), 50];
					_wp setWaypointType "GUARD";
				};
				case "sniper":{
					_activity_params spawn FFUNC(sniper);
				};
				case "homed":{
					_activity_params spawn FFUNC(homed);
				};
				case "civ":{
					_activity_params spawn FFUNC(civilian);
				};
			};
		};
	};
} else {
	{
		_obj_type = _x;
		TRACE_1("Creating Object",_obj_group);
		_obj = [TMF_SERVER_INSTANCE_ID, _obj_type,(_shape select TMF_SHAPE_CENTER),[],((_shape select TMF_SHAPE_WIDTH) max (_shape select TMF_SHAPE_HEIGHT)),_activity] call FFUNC(createVehicle);
		_objs set [count _objs, _obj];
		_obj setPos (_shape select TMF_SHAPE_CENTER);
		_obj setDir (_shape select TMF_SHAPE_ANGLE);
		_obj setVectorUp [0,0,1];
	} foreach _types;
};

if (IS_ARRAY(_objs) && {count _objs == 1}) then { _objs = _objs select 0 };
TRACE_1("End",_objs);
TMFPROFILERSTOP;
_objs;